const Visitor = require("../models/Visitor");
const { generateToken } = require("../utils/jwt");
const { v4: uuidv4 } = require("uuid");
const bcrypt = require("bcryptjs");
const nodemailer = require("nodemailer");
const { encryptData } = require("../utils/encryptionUtils");
const TokenTransaction = require("../models/TokenTransaction"); // 添加TokenTransaction模型
const UserBenefit = require("../models/UserBenefit"); // 添加UserBenefit模型
const { sequelize } = require("../config/database"); // 添加sequelize用于事务
const Redis = require("ioredis"); // 引入ioredis库

// 内存缓存系统作为Redis的备选方案
const memoryCache = {
  store: new Map(),
  set(key, value, expireSeconds) {
    // 存储值和过期时间
    this.store.set(key, {
      value,
      expiry: Date.now() + expireSeconds * 1000
    });
    
    // 设置过期自动清理
    setTimeout(() => {
      this.store.delete(key);
    }, expireSeconds * 1000);
    
    return true;
  },
  get(key) {
    const item = this.store.get(key);
    if (!item) return null;
    
    // 检查是否过期
    if (item.expiry < Date.now()) {
      this.store.delete(key);
      return null;
    }
    
    return item.value;
  },
  del(key) {
    return this.store.delete(key);
  }
};

// 响应消息的多语言配置
const responseMessages = {
  CN: {
    // 验证码发送
    codeSent: "Verification code has been sent to your email, please check",
    // 验证码相关错误
    missingEmail: "Missing required parameter: email",
    emailRegistered: "This email has already been registered",
    missingParams: "Missing required parameters: email, code or password",
    codeInvalidOrExpired:
      "Invalid or expired verification code, please request a new one",
    // 注册成功
    registerSuccess: "Registration successful, 200 tokens gifted",
    // 服务器错误
    serverError: "Internal server error",
    registrationError:
      "An error occurred during registration, please try again later",
  },
  EN: {
    // 验证码发送
    codeSent: "Verification code has been sent to your email, please check",
    // 验证码相关错误
    missingEmail: "Missing required parameter: email",
    emailRegistered: "This email has already been registered",
    missingParams: "Missing required parameters: email, code or password",
    codeInvalidOrExpired:
      "Invalid or expired verification code, please request a new one",
    // 注册成功
    registerSuccess: "Registration successful, 200 tokens gifted",
    // 服务器错误
    serverError: "Internal server error",
    registrationError:
      "An error occurred during registration, please try again later",
  },
  JP: {
    // 验证码发送
    codeSent: "確認コードをメールに送信しました。ご確認ください。", // 验证码相关错误
    missingEmail: "必須項目「メールアドレス」が未入力です。",
    emailRegistered: "このメールアドレスは既に登録されています。",
    missingParams:
      "必要な情報（メールアドレス、確認コード、パスワード）が不足しています。",
    codeInvalidOrExpired:
      "確認コードが無効、または有効期限が切れています。再度コードをリクエストしてください。", // 注册成功

    registerSuccess:
      "ユーザー登録が完了しました。200トークンをプレゼントしました。", // 服务器错误
    serverError: "サーバー内部でエラーが発生しました。",
    registrationError:
      "登録中にエラーが発生しました。しばらくしてから再度お試しください。",
  },
};

// 获取指定语言的响应消息
const getMessage = (key, language = "EN") => {
  const langMessages = responseMessages[language] || responseMessages.EN;
  return langMessages[key] || responseMessages.EN[key];
};

// Redis状态标志
let redisAvailable = false;

// 创建Redis客户端连接
let redis;
try {
  redis = new Redis({
    port: 6379, // Redis默认端口
    host: "127.0.0.1", // 本地Redis服务器地址
    family: 4, // 4 (IPv4) or 6 (IPv6)
    db: 0, // 使用的数据库索引
    maxRetriesPerRequest: 1, // 减少每个请求的重试次数
    connectTimeout: 3000, // 连接超时3秒
    commandTimeout: 3000, // 命令超时3秒
    retryStrategy(times) {
      if (times > 2) {
        // 超过两次重试后放弃
        console.warn("Redis连接重试次数过多，将使用内存缓存替代");
        return null;
      }
      const delay = Math.min(times * 50, 1000);
      return delay;
    },
  });

  // Redis连接错误处理
  redis.on("error", (err) => {
    console.error("Redis连接错误:", err);
    redisAvailable = false;
  });

  // Redis连接成功处理
  redis.on("connect", () => {
    console.log("Redis连接成功");
    redisAvailable = true;
  });
  
  // Redis重新连接处理
  redis.on("reconnecting", () => {
    console.log("Redis尝试重新连接...");
    redisAvailable = false;
  });
} catch (error) {
  console.error("Redis初始化失败:", error);
  redisAvailable = false;
}

// 存储邮箱验证码的内存缓存
const emailVerificationCache = new Map();

// 头像列表
const avatars = [
  "https://www.knomi.me/aiImgas/tx1.png",
  "https://www.knomi.me/aiImgas/tx2.png",
  "https://www.knomi.me/aiImgas/tx3.png",
  "https://www.knomi.me/aiImgas/tx4.png",
  "https://www.knomi.me/aiImgas/tx5.png",
  "https://www.knomi.me/aiImgas/tx6.png",
  "https://www.knomi.me/aiImgas/tx7.png",
  "https://www.knomi.me/aiImgas/tx8.png",
];

// 随机获取头像URL
const getRandomAvatar = () => {
  const randomIndex = Math.floor(Math.random() * avatars.length);
  return avatars[randomIndex];
};

/**
 * 处理访客注册请求
 * @param {Object} req - 请求对象，包含前端生成的uuid
 * @param {Object} res - 响应对象
 */
exports.register = async (req, res) => {
  const transaction = await sequelize.transaction();

  try {
    const { uuid } = req.body;

    // 验证请求
    if (!uuid) {
      await transaction.rollback();
      return res.status(400).json({
        success: false,
        message: "缺少必要参数：uuid",
      });
    }

    // 检查uuid是否已存在
    const existingVisitor = await Visitor.findByPk(uuid, { transaction });
    if (existingVisitor) {
      await transaction.rollback();
      return res.status(409).json({
        success: false,
        message: "此访客ID已注册",
      });
    }

    // 随机分配头像
    const avatar = getRandomAvatar();

    // 创建新访客记录，并添加初始token
    const visitor = await Visitor.create(
      {
        uuid,
        avatar,
        last_login: new Date(),
        login_count: 1,
        status: "active",
        tokens_balance: 200, // 初始赠送200个token
        tokens_promotional: 200, // 记录到促销代币余额
      },
      { transaction }
    );

    // 创建或更新用户权益记录
    let userBenefit = await UserBenefit.findOne({
      where: { user_uuid: uuid },
      transaction,
    });

    if (!userBenefit) {
      userBenefit = await UserBenefit.create(
        {
          user_uuid: uuid,
        },
        { transaction }
      );
    }

    // 记录代币交易
    await TokenTransaction.create(
      {
        user_uuid: uuid,
        type: "promotional_grant",
        amount: 200,
        balance_after: 200,
        description: "新用户注册赠送代币",
        token_source: "promotional",
        status: "confirmed",
        server_type: "promotional",
        payment_order_id: "promotional_" + uuidv4(),
      },
      { transaction }
    );

    // 生成JWT令牌
    const token = generateToken({
      uuid: visitor.uuid,
      type: "visitor",
      last_chat_type: visitor.last_chat_type,
      membership_tier: visitor.membership_tier,
    });

    await transaction.commit();

    // 返回成功响应
    return res.status(201).json({
      success: true,
      message: "访客注册成功，已赠送200代币",
      data: {
        uuid: visitor.uuid,
        avatar: visitor.avatar,
        last_chat_type: visitor.last_chat_type,
        token,
        expiresIn: process.env.JWT_EXPIRES_IN,
        tokens_balance: visitor.tokens_balance,
      },
    });
  } catch (error) {
    await transaction.rollback();
    console.error("访客注册错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 处理访客登录请求
 * @param {Object} req - 请求对象，包含uuid
 * @param {Object} res - 响应对象
 */
exports.login = async (req, res) => {
  try {
    const { uuid } = req.body;

    // 验证请求
    if (!uuid) {
      return res.status(400).json({
        success: false,
        message: "缺少必要参数：uuid",
      });
    }

    // 查找访客
    const visitor = await Visitor.findByPk(uuid);
    if (!visitor) {
      return res.status(404).json({
        success: false,
        message: "访客不存在，请先注册",
      });
    }

    // 检查访客状态
    if (visitor.status !== "active") {
      return res.status(403).json({
        success: false,
        message: "访客账号已被禁用",
      });
    }

    // 更新登录信息
    await visitor.update({
      last_login: new Date(),
      login_count: visitor.login_count + 1,
    });

    // 生成新的JWT令牌
    const token = generateToken({
      uuid: visitor.uuid,
      type: "visitor",
      last_chat_type: visitor.last_chat_type,
      membership_tier: visitor.membership_tier,
    });

    // 返回成功响应
    return res.status(200).json({
      success: true,
      message: "访客登录成功",
      data: {
        uuid: visitor.uuid,
        avatar: visitor.avatar,
        last_chat_type: visitor.last_chat_type,
        token,
        expiresIn: process.env.JWT_EXPIRES_IN,
      },
    });
  } catch (error) {
    console.error("访客登录错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 获取推荐的新UUID（辅助接口）
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 */
exports.generateUuid = async (req, res) => {
  try {
    // 生成新的UUID
    const uuid = uuidv4();

    return res.status(200).json({
      success: true,
      message: "生成UUID成功",
      data: { uuid },
    });
  } catch (error) {
    console.error("生成UUID错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 生成六位数随机验证码（只包含大写字母和数字）
 * @returns {string} 六位数验证码
 */
const generateVerificationCode = () => {
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  let code = "";
  for (let i = 0; i < 6; i++) {
    const randomIndex = Math.floor(Math.random() * characters.length);
    code += characters[randomIndex];
  }
  return code;
};

/**
 * 发送验证码邮件
 * @param {string} email - 收件人邮箱
 * @param {string} code - 验证码
 * @param {string} language - 语言选项
 * @returns {Promise<boolean>} 发送结果
 */
const sendVerificationEmail = async (email, code, language = "CN") => {
  try {
    // 邮件内容配置
    const emailContent = {
      CN: {
        subject: "Know1 邮箱验证码",
        title: "邮箱验证码",
        greeting: "您好！",
        message: "感谢您注册 Know1 账号。请使用以下验证码完成注册：",
        expiry: "验证码有效期为 10 分钟。",
        footer1: "此邮件由系统自动发送，请勿回复",
        footer2: "如有疑问，请联系我们的客服团队",
      },
      EN: {
        subject: "Know1 Email Verification Code",
        title: "Email Verification Code",
        greeting: "Hello!",
        message:
          "Thank you for registering a Know1 account. Please use the following verification code to complete your registration:",
        expiry: "The verification code is valid for 10 minutes.",
        footer1:
          "This email is automatically sent by the system. Please do not reply.",
        footer2:
          "If you have any questions, please contact our customer service team",
      },
      JP: {
        subject: "Know1 メール確認コード",
        title: "メール確認コード",
        greeting: "こんにちは！",
        message:
          "Know1 アカウントへの登録をありがとうございます。以下の確認コードを使用して登録を完了してください：",
        expiry: "確認コードの有効期間は 10 分間です。",
        footer1:
          "このメールはシステムによって自動的に送信されます。返信しないでください。",
        footer2:
          "ご質問がある場合は、カスタマーサービスチームにお問い合わせください",
      },
    };

    // 获取对应语言的内容
    const content = emailContent[language] || emailContent.CN;

    // 创建邮件传输对象，添加重试机制
    const transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: process.env.SMTP_PORT,
      secure: true,
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS,
      },
      tls: {
        rejectUnauthorized: true,
      },
      connectionTimeout: 300000, // 30秒
      greetingTimeout: 300000,
      socketTimeout: 300000,
      pool: true, // 使用连接池
      maxConnections: 5, // 最大连接数
      maxMessages: 100, // 每个连接的最大消息数
    });

    // 发送邮件，添加重试机制
    let retryCount = 0;
    const maxRetries = 3;

    while (retryCount <= maxRetries) {
      try {
        await transporter.sendMail({
          from: '"Know1" <noreply@know1.ai>',
          to: email,
          subject: content.subject,
          html: `
          <!DOCTYPE html>
          <html lang="${
            language === "EN" ? "en" : language === "JP" ? "ja" : "zh-CN"
          }">
          <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>${content.title}</title>
            <style>
              body {
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                line-height: 1.6;
                color: #131313;
                margin: 0;
                padding: 0;
              }
              .container {
                max-width: 600px;
                margin: 20px auto;
                border-radius: 10px;
                box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
                overflow: hidden;
              }
              .header {
                background: rgba(0, 0, 0);
                color: white;
                padding: 30px;
                text-align: center;
              }
              .header h1 {
                margin: 0;
                font-size: 24px;
                font-weight: 300;
              }
              .content {
                padding: 40px 30px;
                background-color: #f8f9fa;
              }
              .message {
                font-size: 16px;
                margin-bottom: 30px;
              }
              .code {
                font-size: 32px;
                font-weight: bold;
                text-align: center;
                padding: 15px;
                margin: 20px 0;
                background-color: #f1f1f1;
                border-radius: 5px;
                letter-spacing: 8px;
                color: #e1768a;
              }
              .footer {
                padding: 20px 30px;
                text-align: center;
                color: #6c757d;
                font-size: 14px;
                background-color: rgba(0, 0, 0);
              }
              .logo {
                margin-bottom: 20px;
              }
              .logo img {
                max-width: 200px;
                height: auto;
              }
            </style>
          </head>
          <body>
            <div class="container">
              <div class="header">
                <div class="logo">
                  <img src="https://www.knomi.me/resource_AiPersion/Ai_persion/Images/Know1_logo.png" alt="Know1 Logo">
                </div>
                <h1>${content.title}</h1>
              </div>
              
              <div class="content">
                <div class="message">
                  <p>${content.greeting}</p>
                  <p>${content.message}</p>
                </div>
                
                <div class="code">${code}</div>
                
                <p style="text-align: center; color: #6c757d;">${
                  content.expiry
                }</p>
              </div>
              
              <div class="footer">
                <p>${content.footer1}</p>
                <p>${content.footer2}</p>
              </div>
            </div>
          </body>
          </html>
          `,
        });

        // 发送成功
        return true;
      } catch (error) {
        retryCount++;

        // 如果达到最大重试次数，抛出错误
        if (retryCount > maxRetries) {
          console.error(`邮件发送失败，已重试${maxRetries}次:`, error);
          throw error;
        }

        // 等待一段时间后重试
        await new Promise((resolve) => setTimeout(resolve, 1000 * retryCount));
      }
    }
  } catch (error) {
    console.error("发送验证邮件错误:", error);
    throw error;
  }
};

/**
 * 将验证码存储到Redis或内存缓存
 * @param {string} email - 邮箱地址
 * @param {string} code - 验证码
 * @returns {Promise<boolean>} 存储结果
 */
const storeVerificationCode = async (email, code) => {
  try {
    // 邮箱转小写，验证码转大写，确保不区分大小写
    const normalizedEmail = email.trim().toLowerCase();
    const normalizedCode = code.toUpperCase();
    const cacheKey = `email_verification:${normalizedEmail}`;
    
    // 首先尝试使用Redis
    if (redisAvailable && redis) {
      try {
        // 添加超时控制
        const storePromise = redis.set(cacheKey, normalizedCode, "EX", 600);
        const timeoutPromise = new Promise((_, reject) => {
          setTimeout(() => reject(new Error("Redis存储操作超时")), 3000);
        });
        
        // 如果3秒内Redis操作没有完成，则认为操作超时
        await Promise.race([storePromise, timeoutPromise]);
        console.log("验证码已存储到Redis");
        return true;
      } catch (redisError) {
        console.warn("Redis存储验证码失败，将使用内存缓存:", redisError.message);
      }
    }
    
    // Redis不可用或存储失败，使用内存缓存
    console.log("使用内存缓存存储验证码");
    memoryCache.set(cacheKey, normalizedCode, 600); // 10分钟有效期
    return true;
  } catch (error) {
    console.error("存储验证码错误:", error);
    // 即使出错也返回成功，避免阻塞注册流程
    return true;
  }
};

/**
 * 验证邮箱验证码
 * @param {string} email - 邮箱地址
 * @param {string} code - 用户输入的验证码
 * @returns {Promise<boolean>} 验证结果
 */
const verifyEmailCode = async (email, code) => {
  try {
    // 将邮箱和验证码都标准化处理，确保不区分大小写
    const normalizedEmail = email.trim().toLowerCase();
    const normalizedCode = code.trim().toUpperCase();
    const cacheKey = `email_verification:${normalizedEmail}`;
    
    let storedCode = null;
    
    // 首先尝试从Redis获取
    if (redisAvailable && redis) {
      try {
        // 添加超时控制
        const getPromise = redis.get(cacheKey);
        const timeoutPromise = new Promise((_, reject) => {
          setTimeout(() => reject(new Error("Redis获取操作超时")), 3000);
        });
        
        // 如果3秒内Redis操作没有完成，则认为操作超时
        storedCode = await Promise.race([getPromise, timeoutPromise]);
        console.log("从Redis获取验证码");
      } catch (redisError) {
        console.warn("从Redis获取验证码失败，将检查内存缓存:", redisError.message);
      }
    }
    
    // Redis不可用或获取失败时，尝试从内存缓存获取
    if (storedCode === null) {
      console.log("从内存缓存获取验证码");
      storedCode = memoryCache.get(cacheKey);
    }

    // 验证码不存在或已过期
    if (!storedCode) {
      console.log("验证码不存在或已过期");
      return false;
    }

    // 验证码比较（不区分大小写，将存储的验证码也转为大写）
    if (storedCode.toUpperCase() !== normalizedCode) {
      console.log("验证码不匹配");
      return false;
    }

    // 验证通过，删除验证码防止重复使用
    try {
      if (redisAvailable && redis) {
        redis.del(cacheKey).catch(err => {
          console.warn("从Redis删除验证码失败:", err.message);
        });
      }
      memoryCache.del(cacheKey);
      console.log("验证码验证通过，已删除验证码");
    } catch (e) {
      // 忽略删除失败的错误
      console.warn("删除验证码时出错:", e.message);
    }
    
    return true;
  } catch (error) {
    console.error("验证码验证错误:", error);
    // 当验证出错时，为了安全起见，返回验证失败
    return false;
  }
};

/**
 * 正式用户注册第一步 - 发送验证码
 * @param {Object} req - 请求对象，包含 email
 * @param {Object} res - 响应对象
 */
exports.registerUser = async (req, res) => {
  try {
    const { email, language = "EN" } = req.body;
    console.log("注册请求:", email, language);
    
    // 校验 email
    if (!email) {
      return res.status(400).json({
        success: false,
        message: getMessage("missingEmail", language),
      });
    }

    // 标准化邮箱（转为小写）
    const normalizedEmail = email.trim().toLowerCase();

    // 检查 email 是否已注册（不区分大小写）
    const existingUser = await Visitor.findOne({
      where: {
        email: normalizedEmail,
      },
    });

    if (existingUser) {
      return res.status(409).json({
        success: false,
        message: getMessage("emailRegistered", language),
      });
    }

    // 生成验证码
    const verificationCode = generateVerificationCode();
    console.log(`为 ${normalizedEmail} 生成验证码: ${verificationCode}`);

    // 存储验证码到缓存系统(Redis或内存)
    let codeStored = false;
    try {
      await storeVerificationCode(normalizedEmail, verificationCode);
      codeStored = true;
    } catch (storageError) {
      console.error("存储验证码失败:", storageError);
      // 即使存储失败也继续流程，因为storeVerificationCode已经做了内存缓存备份
    }

    // 发送验证码邮件 - 使用Promise.race添加超时控制
    let emailSent = false;
    try {
      const emailPromise = sendVerificationEmail(normalizedEmail, verificationCode, language);
      const timeoutPromise = new Promise((_, reject) => {
        setTimeout(() => reject(new Error("邮件发送操作超时")), 10000); // 10秒超时
      });
      
      await Promise.race([emailPromise, timeoutPromise]);
      emailSent = true;
    } catch (emailError) {
      console.error("发送验证码邮件失败:", emailError);
      // 即使邮件发送失败，也继续流程
    }

    // 返回响应 - 记录可能的问题但仍然视为成功
    const responseMessage = emailSent 
      ? getMessage("codeSent", language)
      : "验证码已生成，但邮件发送可能延迟，请稍后检查邮箱或尝试重新获取";

    return res.status(200).json({
      success: true,
      message: responseMessage,
      data: {
        email: normalizedEmail,
      },
      // 仅在开发环境中返回这些调试信息
      debug: process.env.NODE_ENV === "development" ? {
        codeStored,
        emailSent,
        redisAvailable
      } : undefined
    });
  } catch (error) {
    console.error("发送验证码错误:", error);
    const language = req.body.language || "EN"; // 确保即使出错也能获取语言设置
    return res.status(500).json({
      success: false,
      message: getMessage("serverError", language),
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 正式用户注册第二步 - 验证验证码并创建用户
 * @param {Object} req - 请求对象，包含 email，code 和 password
 * @param {Object} res - 响应对象
 */
exports.verifyEmailAndRegister = async (req, res) => {
  let transaction;

  try {
    const { email, code, password, language = "EN" } = req.body;

    // 标准化邮箱（转为小写）
    const normalizedEmail = email ? email.trim().toLowerCase() : null;

    // 校验参数
    if (!normalizedEmail || !code || !password) {
      return res.status(400).json({
        success: false,
        message: getMessage("missingParams", language),
      });
    }

    // 验证验证码
    const isCodeValid = await verifyEmailCode(normalizedEmail, code);
    if (!isCodeValid) {
      return res.status(400).json({
        success: false,
        message: getMessage("codeInvalidOrExpired", language),
      });
    }

    // 开始数据库事务，添加重试机制
    let retryCount = 0;
    const maxRetries = 3;
    let user, userBenefit, tokenTransaction, token;

    while (retryCount <= maxRetries) {
      try {
        transaction = await sequelize.transaction();

        // 随机分配头像
        const avatar = getRandomAvatar();

        // 生成 uuid
        const uuid = uuidv4();

        // 密码加密
        const hashedPassword = await bcrypt.hash(password, 10);

        // 创建新用户，并添加初始token
        user = await Visitor.create(
          {
            uuid,
            email: normalizedEmail,
            password: hashedPassword,
            displayName: normalizedEmail,
            avatar,
            last_login: new Date(),
            login_count: 1,
            status: "active",
            tokens_balance: 200, // 初始赠送200个token
            tokens_promotional: 200, // 记录到促销代币余额
            gender: null, // 明确设置性别为null
          },
          { transaction }
        );

        // 创建或更新用户权益记录
        userBenefit = await UserBenefit.findOne({
          where: { user_uuid: uuid },
          transaction,
        });

        if (!userBenefit) {
          userBenefit = await UserBenefit.create(
            {
              user_uuid: uuid,
            },
            { transaction }
          );
        }

        // 记录代币交易
        tokenTransaction = await TokenTransaction.create(
          {
            user_uuid: uuid,
            type: "promotional_grant",
            amount: 200,
            balance_after: 200,
            description: "新用户注册赠送代币",
            token_source: "promotional",
            status: "confirmed",
            server_type: "promotional",
            payment_order_id: "promotional_" + uuidv4(),
          },
          { transaction }
        );

        // 生成 JWT 令牌
        token = generateToken({
          uuid: user.uuid,
          type: "visitor",
          last_chat_type: user.last_chat_type,
          membership_tier: user.membership_tier,
        });

        await transaction.commit();
        break; // 事务成功，跳出循环
      } catch (error) {
        if (transaction) await transaction.rollback();

        // 检查是否是数据库连接或锁定错误
        const isConnectionError =
          error.name === "SequelizeConnectionError" ||
          error.name === "SequelizeConnectionRefusedError" ||
          error.name === "SequelizeConnectionTimedOutError" ||
          error.name === "SequelizeConnectionAcquireTimeoutError" ||
          (error.message && error.message.includes("deadlock"));

        retryCount++;

        if (isConnectionError && retryCount <= maxRetries) {
          // 使用指数退避策略
          const delay = Math.pow(2, retryCount) * 1000;
          console.log(
            `数据库事务错误，${
              delay / 1000
            }秒后重试 (${retryCount}/${maxRetries})`,
            error
          );
          await new Promise((resolve) => setTimeout(resolve, delay));
          continue;
        }

        // 其他错误或已达到最大重试次数
        console.error("用户注册错误:", error);
        return res.status(500).json({
          success: false,
          message: getMessage("registrationError", language),
          error:
            process.env.NODE_ENV === "development" ? error.message : undefined,
        });
      }
    }

    // 如果超过重试次数仍未成功
    if (!user) {
      return res.status(500).json({
        success: false,
        message: getMessage("registrationError", language),
      });
    }

    // 返回成功响应
    return res.status(201).json({
      success: true,
      message: getMessage("registerSuccess", language),
      data: {
        uuid: user.uuid,
        avatar: user.avatar,
        last_chat_type: user.last_chat_type,
        token,
        expiresIn: process.env.JWT_EXPIRES_IN,
        tokens_balance: user.tokens_balance,
      },
    });
  } catch (error) {
    if (transaction) await transaction.rollback();
    console.error("验证邮箱并注册错误:", error);
    const language = req.body.language || "EN"; // 确保即使出错也能获取语言设置
    return res.status(500).json({
      success: false,
      message: getMessage("serverError", language),
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

// 通过邮箱+密码登录
exports.loginWithEmail = async (req, res) => {
  try {
    const { email, password, language = "EN" } = req.body; // 新增 language 参数，默认英文
    if (!email || !password) {
      return res.status(400).json({
        success: false,
        message: getMessage("missingParams", language),
      });
    }
    // 查找用户
    const user = await Visitor.findOne({ where: { email } });
    if (!user) {
      return res.status(404).json({
        success: false,
        message:
          language === "JP"
            ? "ユーザーが存在しません。まずはご登録ください。"
            : language === "EN"
            ? "User does not exist, please register first."
            : "用户不存在，请先注册",
      });
    }
    // 检查用户状态
    if (user.status !== "active") {
      return res.status(403).json({
        success: false,
        message:
          language === "JP"
            ? "アカウントが無効化されています"
            : language === "EN"
            ? "Account has been disabled"
            : "账号已被禁用",
      });
    }
    // 检查密码
    if (!user.password) {
      return res.status(400).json({
        success: false,
        message:
          language === "JP"
            ? "このアカウントはパスワードが設定されていません。他の方法でログインしてください。"
            : language === "EN"
            ? "The account has not set a password, please use other methods to login."
            : "该账号未设置密码，请使用其他方式登录",
      });
    }
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) {
      return res.status(401).json({
        success: false,
        message:
          language === "JP"
            ? "パスワードが正しくありません"
            : language === "EN"
            ? "Password is incorrect"
            : "密码错误",
      });
    }
    // 更新登录信息
    await user.update({
      last_login: new Date(),
      login_count: user.login_count + 1,
    });
    // 生成 token
    const token = generateToken({
      uuid: user.uuid,
      type: "visitor",
      last_chat_type: user.last_chat_type,
      membership_tier: user.membership_tier,
    });
    return res.status(200).json({
      success: true,
      message:
        language === "JP"
          ? "ログイン成功"
          : language === "EN"
          ? "Login successful"
          : "登录成功",
      data: {
        uuid: user.uuid,
        avatar: user.avatar,
        last_chat_type: user.last_chat_type,
        token,
        expiresIn: process.env.JWT_EXPIRES_IN,
      },
    });
  } catch (error) {
    console.error("邮箱密码登录错误:", error);
    const language = req.body.language || "EN";
    return res.status(500).json({
      success: false,
      message:
        language === "JP"
          ? "サーバー内部でエラーが発生しました。"
          : language === "EN"
          ? "Server internal error"
          : "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

// 忘记密码：请求重置密码邮件
exports.requestPasswordReset = async (req, res) => {
  try {
    const { email, language = "CN" } = req.body;
    if (!email) {
      return res.status(400).json({
        success: false,
        message: "Missing required parameter: email", // 缺少必要参数：email
      });
    }
    // 查找用户
    const user = await Visitor.findOne({ where: { email } });
    if (!user) {
      return res.status(404).json({
        success: false,
        message: "The email has not been registered", // 该邮箱未注册
      });
    }
    // 生成 token 和过期时间
    const crypto = require("crypto");
    const resetToken = crypto.randomBytes(32).toString("hex");
    const expires = new Date(Date.now() + 1000 * 60 * 30); // 30分钟有效
    await user.update({
      reset_password_token: resetToken,
      reset_password_expires: expires,
    });
    // 构造重置链接
    // const resetUrl = `https:///http://192.168.31.86:5173/test/#/setPassWord?reset_password_token=${resetToken}`; // 开发环境地址
    const resetUrl = `https://www.know1.ai/setPassWord?reset_password_token=${resetToken}`; // 生产环境地址
    // 发送邮件
    // 请根据实际情况配置 transporter
    const transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: process.env.SMTP_PORT,
      secure: true,
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS,
      },
      tls: {
        rejectUnauthorized: true, // 解决SSL证书问题
      },
      connectionTimeout: 300000, // 30秒
      greetingTimeout: 300000,
      socketTimeout: 300000,
    });
    // 多语言内容配置
    const emailContent = {
      CN: {
        subject: "密码重置请求",
        title: "密码重置请求",
        greeting:
          "您好！我们收到了您的密码重置请求。如果这不是您本人的操作，请忽略此邮件。",
        expiryWarning:
          "⚠️ 重要提醒：此重置链接将在 30 分钟后过期，请及时使用。",
        resetLinkText: "请复制以下链接到浏览器地址栏进行密码重置：",
        securityTips: "安全提示：",
        securityTip1: "请确保您在安全的网络环境下操作",
        securityTip2: "不要将重置链接分享给他人",
        securityTip3: "设置密码时请使用强密码（包含字母、数字和特殊字符）",
        footer1: "此邮件由 KnowYou 系统自动发送，请勿回复",
        footer2: "如有疑问，请联系我们的客服团队",
      },
      EN: {
        subject: "Password Reset Request",
        title: "Password Reset Request",
        greeting:
          "Hello! We received your password reset request. If this was not initiated by you, please ignore this email.",
        expiryWarning:
          "⚠️ Important: This reset link will expire in 30 minutes. Please use it promptly.",
        resetLinkText:
          "Please copy the following link to your browser address bar to reset your password:",
        securityTips: "Security Tips:",
        securityTip1:
          "Please ensure you are operating in a secure network environment",
        securityTip2: "Do not share the reset link with others",
        securityTip3:
          "When setting a password, please use a strong password (containing letters, numbers, and special characters)",
        footer1:
          "This email is automatically sent by the KnowYou system. Please do not reply.",
        footer2:
          "If you have any questions, please contact our customer service team",
      },
      JP: {
        subject: "パスワードリセットリクエスト",
        title: "パスワードリセットリクエスト",
        greeting:
          "こんにちは！パスワードリセットリクエストを受信しました。これがあなたの操作でない場合は、このメールを無視してください。",
        expiryWarning:
          "⚠️ 重要：このリセットリンクは30分後に期限切れになります。お早めにご利用ください。",
        resetLinkText:
          "パスワードをリセットするには、以下のリンクをブラウザのアドレスバーにコピーしてください：",
        securityTips: "セキュリティのヒント：",
        securityTip1:
          "安全なネットワーク環境で操作していることを確認してください",
        securityTip2: "リセットリンクを他の人と共有しないでください",
        securityTip3:
          "パスワードを設定する際は、強力なパスワード（文字、数字、特殊文字を含む）を使用してください",
        footer1:
          "このメールはKnowYouシステムによって自動送信されます。返信しないでください。",
        footer2:
          "ご質問がございましたら、カスタマーサービスチームまでお問い合わせください",
      },
    };

    // 获取对应语言的内容
    const content = emailContent[language] || emailContent.CN;

    await transporter.sendMail({
      from: process.env.SMTP_USER,
      to: email,
      subject: content.subject,
      html: `
     <!DOCTYPE html>
<html lang="${language === "EN" ? "en" : language === "JP" ? "ja" : "zh-CN"}">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${content.title}</title>
  <style>
    @font-face {
      font-family: 'ENnFont';
      src: url('https://www.know1.ai/assets/fonts/ENnFont/pxiByp8kv8JHgFVrLGT9Z1xlFQ.woff2') format('woff2');
      font-weight: normal;
      font-style: normal;
      font-display: swap;
    }
    
    body {
      font-family: 'ENnFont', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      line-height: 1.6;
      color: #131313;
      margin: 0;
      padding: 0;
    }
    .container {
      max-width: 600px;
      margin: 20px auto;
      border-radius: 10px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      overflow: hidden;
    }
    .header {
      background: rgba(0, 0, 0, 0.9);
      color: white;
      padding: 30px;
      text-align: center;
    }
    .header h1 {
      margin: 0;
      font-size: 24px;
      font-weight: 300;
      font-family: 'ENnFont', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    .content {
      padding: 40px 30px;
      background-image: url('https://www.know1.ai/resource_AiPersion/MBTI/4ed1cd47-2e4e-4c0e-b41d-1b73381758fc.webp');
      background-size: cover;
      background-position: center;
      background-attachment: local;
      background-color: rgba(19, 19, 19, 0.6);
      background-blend-mode: overlay;
    }
    .message {
      font-size: 16px;
      margin-bottom: 30px;
      color: rgb(225, 118, 138);
      font-weight: 600;
      font-family: 'ENnFont', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: rgba(255, 255, 255, 0.8);
      padding: 15px;
      border-radius: 5px;
    }
    .warning {
      background-color: rgba(255, 255, 255, 0.8);
      border: 1px solid #ffeaa7;
      border-radius: 5px;
      padding: 15px;
      margin: 20px 0;
      color: #856404;
      font-family: 'ENnFont', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    .footer {
      padding: 20px 30px;
      text-align: center;
      color: #6c757d;
      font-size: 14px;
      font-family: 'ENnFont', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: rgba(0, 0, 0, 0.9);
    }
    .logo {
      margin-bottom: 20px;
    }
    .logo img {
      max-width: 200px;
      height: auto;
    }
    .expiry-info {
      background-color: rgba(227, 242, 253, 0.8);
      border-left: 4px solid rgb(225, 118, 138);
      padding: 15px;
      margin: 20px 0;
      color: #1976d2;
      font-family: 'ENnFont', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    .reset-link {
      background-color: rgba(248, 249, 250, 0.8);
      border: 2px solid rgb(225, 118, 138);
      border-radius: 8px;
      padding: 15px;
      margin: 20px 0;
      word-break: break-all;
      font-family: 'ENnFont', 'Courier New', monospace;
      font-size: 12px;
      color: rgb(225, 118, 138);
      text-decoration: none;
    }
    .reset-link:hover {
      background-color: rgb(225, 118, 138);
      color: white;
    }
    .illustration {
      text-align: center;
      margin: 30px 0;
      padding: 20px;
      background-color: rgba(255, 255, 255, 0.8);
      border-radius: 10px;
    }
    .illustration img {
      max-width: 300px;
      height: auto;
      border-radius: 10px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <div class="logo">
        <img src="https://www.know1.ai/resource_AiPersion/Ai_persion/Images/Know1_logo.png" alt="Know1 Logo">
      </div>
      <h1>${content.title}</h1>
    </div>
    
    <div class="content">
      <div class="message">
        ${content.greeting}
      </div>
      
      <div class="expiry-info">
        <strong>${content.expiryWarning}</strong>
      </div>
      
      <div style="margin: 20px 0;">
        <p style="font-weight: 600; color:rgb(225, 118, 138); font-size: 14px; margin-bottom: 10px;">
          <strong>${content.resetLinkText}</strong>
        </p>
        <div class="reset-link">
          ${resetUrl}
        </div>
      </div>
      
      <div class="warning">
        <strong>${content.securityTips}</strong>
        <ul style="margin: 10px 0; padding-left: 20px;">
          <li>${content.securityTip1}</li>
          <li>${content.securityTip2}</li>
          <li>${content.securityTip3}</li>
        </ul>
      </div>
    </div>
    
    <div class="footer">
      <p>${content.footer1}</p>
      <p>${content.footer2}</p>
    </div>
  </div>
</body>
</html>


      `,
    });
    return res.status(200).json({
      success: true,
      message: "重置密码邮件已发送，请查收邮箱",
    });
  } catch (error) {
    console.error("请求重置密码错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

// 重置密码
exports.resetPassword = async (req, res) => {
  try {
    const { reset_password_token, newPassword, confirmPassword } = req.body;
    if (!reset_password_token || !newPassword || !confirmPassword) {
      return res.status(400).json({
        success: false,
        message: "缺少必要参数",
      });
    }
    if (newPassword !== confirmPassword) {
      return res.status(400).json({
        success: false,
        message: "两次输入的密码不一致",
      });
    }
    // 查找用户
    const user = await Visitor.findOne({ where: { reset_password_token } });
    if (!user) {
      return res.status(400).json({
        success: false,
        message: "无效的重置链接或token",
      });
    }
    // 检查 token 是否过期
    if (
      !user.reset_password_expires ||
      user.reset_password_expires < new Date()
    ) {
      return res.status(400).json({
        success: false,
        message: "重置链接已过期，请重新申请",
      });
    }
    // 加密新密码
    const hashedPassword = await bcrypt.hash(newPassword, 10);
    // 更新密码并清空 token 字段
    await user.update({
      password: hashedPassword,
      reset_password_token: null,
      reset_password_expires: null,
    });
    // 颁发新 token
    const token = generateToken({
      uuid: user.uuid,
      type: "visitor",
      last_chat_type: user.last_chat_type,
      membership_tier: user.membership_tier,
    });
    return res.status(200).json({
      success: true,
      message: "密码重置成功",
      data: {
        uuid: user.uuid,
        avatar: user.avatar,
        last_chat_type: user.last_chat_type,
        token,
        expiresIn: process.env.JWT_EXPIRES_IN,
      },
    });
  } catch (error) {
    console.error("重置密码错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 获取用户信息接口
 * @param {Object} req - 请求对象，包含查询参数fields
 * @param {Object} res - 响应对象
 */
exports.getUserInformation = async (req, res) => {
  try {
    // 从中间件获取用户UUID
    const { uuid } = req.visitor;

    // 获取查询参数fields
    const { fields } = req.query;

    if (!fields) {
      return res.status(400).json({
        success: false,
        message: "缺少必要参数：fields（需要查询的字段列表）",
      });
    }

    // 解析fields参数
    const requestedFields = fields.split(",").map((field) => field.trim());

    // 定义允许查询的字段映射
    const allowedFields = {
      avatar: "avatar",
      displayName: "displayName",
      gender: "gender",
      email: "email",
      password: "password",
      phone: "phone",
      membershipTier: "membership_tier",
      tokensBalance: "tokens_balance",
      tokensPurchased: "tokens_purchased",
      tokensPromotional: "tokens_promotional",
      tokensCompensated: "tokens_compensated",
    };

    // 验证请求的字段是否合法
    const invalidFields = requestedFields.filter(
      (field) => !allowedFields[field]
    );
    if (invalidFields.length > 0) {
      return res.status(400).json({
        success: false,
        message: `无效的字段：${invalidFields.join(
          ", "
        )}。支持的字段：${Object.keys(allowedFields).join(", ")}`,
      });
    }

    // 构建查询字段数组
    const dbFields = ["uuid"]; // 始终包含uuid用于查询
    requestedFields.forEach((field) => {
      dbFields.push(allowedFields[field]);
    });

    // 查询用户信息
    const user = await Visitor.findByPk(uuid, {
      attributes: dbFields,
    });

    if (!user) {
      return res.status(404).json({
        success: false,
        message: "用户不存在",
      });
    }

    // 构建返回数据
    const userData = {};
    requestedFields.forEach((field) => {
      const dbField = allowedFields[field];
      userData[field] = user[dbField];
    });

    // 加密数据
    const encryptedData = encryptData(userData);

    return res.status(200).json({
      success: true,
      message: "获取用户信息成功",
      data: {
        encryptedData: encryptedData,
        timestamp: new Date().toISOString(),
      },
    });
  } catch (error) {
    console.error("获取用户信息错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 修改用户信息接口
 * @param {Object} req - 请求对象，body中包含要修改的字段
 * @param {Object} res - 响应对象
 */
exports.updateUserInformation = async (req, res) => {
  try {
    const { uuid } = req.visitor;
    const { displayName, gender, phone } = req.body;

    // 检查是否有要更新的字段
    if (
      displayName === undefined &&
      gender === undefined &&
      phone === undefined
    ) {
      return res.status(400).json({
        success: false,
        message: "缺少要更新的字段（displayName, gender, phone）",
      });
    }

    // 构建要更新的字段对象
    const updateFields = {};
    if (displayName !== undefined) updateFields.displayName = displayName;
    if (gender !== undefined) updateFields.gender = gender;
    if (phone !== undefined) updateFields.phone = phone;

    // 更新用户信息
    const [affectedRows] = await Visitor.update(updateFields, {
      where: { uuid },
    });
    if (affectedRows === 0) {
      return res.status(404).json({
        success: false,
        message: "用户不存在或无可更新字段",
      });
    }

    return res.status(200).json({
      success: true,
      message: "用户信息更新成功",
      data: updateFields,
    });
  } catch (error) {
    console.error("更新用户信息错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 修改用户密码接口
 * @param {Object} req - 请求对象，body中包含 newPassWord 和 oldPassWord
 * @param {Object} res - 响应对象
 */
exports.updateUserPassword = async (req, res) => {
  try {
    const { uuid } = req.visitor;
    const { newPassWord, oldPassWord } = req.body;

    if (!newPassWord) {
      return res.status(400).json({
        success: false,
        message: "缺少新密码 newPassWord",
      });
    }

    // 查询用户
    const user = await Visitor.findByPk(uuid);
    if (!user) {
      return res.status(404).json({
        success: false,
        message: "用户不存在",
      });
    }

    // 如果数据库中已有密码，校验旧密码
    if (user.password) {
      if (!oldPassWord) {
        return res.status(400).json({
          success: false,
          message: "缺少旧密码 oldPassWord",
        });
      }
      const isMatch = await bcrypt.compare(oldPassWord, user.password);
      if (!isMatch) {
        return res.status(401).json({
          success: false,
          message: "旧密码不正确",
        });
      }
    }

    // 更新新密码
    const hashedPassword = await bcrypt.hash(newPassWord, 10);
    await user.update({ password: hashedPassword });

    return res.status(200).json({
      success: true,
      message: "密码修改成功",
    });
  } catch (error) {
    console.error("修改密码错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 修改用户头像接口
 * @param {Object} req - 请求对象，包含上传的文件
 * @param {Object} res - 响应对象
 */
exports.updateUserAvatar = async (req, res) => {
  try {
    // 优先从请求头获取uuid，如果没有则从Authorization token中提取
    let uuid = req.headers.uuid;

    if (!uuid) {
      // 尝试从Authorization header中提取token并解析uuid
      const authHeader = req.headers.authorization;
      if (authHeader && authHeader.startsWith("Bearer ")) {
        try {
          const token = authHeader.substring(7); // 移除 'Bearer ' 前缀
          const jwt = require("jsonwebtoken");
          const decoded = jwt.verify(token, process.env.JWT_SECRET);
          uuid = decoded.uuid;
        } catch (jwtError) {
          return res.status(401).json({
            success: false,
            message: "无效的认证令牌",
          });
        }
      }
    }

    if (!uuid) {
      return res.status(400).json({
        success: false,
        message:
          "缺少必要参数：uuid（可通过uuid请求头或Authorization Bearer token提供）",
      });
    }

    const file = req.file;

    if (!file) {
      return res.status(400).json({
        success: false,
        message: "没有上传文件",
      });
    }

    // 验证文件类型（只允许图片）
    const allowedImageTypes = [
      "image/jpeg",
      "image/jpg",
      "image/png",
      "image/gif",
      "image/webp",
      "image/bmp",
    ];
    if (!allowedImageTypes.includes(file.mimetype)) {
      // 清理临时文件
      const fs = require("fs");
      if (fs.existsSync(file.path)) {
        fs.unlinkSync(file.path);
      }
      return res.status(400).json({
        success: false,
        message: "只支持图片格式文件（jpg, png, gif, webp, bmp）",
      });
    }

    // 使用新的OSS上传功能，上传到根目录的usersImage目录
    const ossManager = require("../utils/ossUtils");
    const customFileName = `avatar_${uuid}_${Date.now()}${require("path").extname(
      file.originalname
    )}`;

    const result = await ossManager.uploadFileToRootFolder(
      file.path,
      "usersImage",
      customFileName
    );

    if (!result.success) {
      // 清理临时文件
      const fs = require("fs");
      if (fs.existsSync(file.path)) {
        fs.unlinkSync(file.path);
      }
      return res.status(400).json({
        success: false,
        message: "头像上传失败",
        error: result.error,
      });
    }

    // 更新用户头像URL
    const [affectedRows] = await Visitor.update(
      { avatar: result.customUrl },
      { where: { uuid } }
    );

    if (affectedRows === 0) {
      return res.status(404).json({
        success: false,
        message: "用户不存在",
      });
    }

    // 清理临时文件
    const fs = require("fs");
    if (fs.existsSync(file.path)) {
      fs.unlinkSync(file.path);
    }

    return res.status(200).json({
      success: true,
      message: "头像修改成功",
      data: {
        avatar: result.customUrl,
      },
    });
  } catch (error) {
    console.error("修改头像错误:", error);

    // 清理临时文件
    if (req.file && req.file.path) {
      const fs = require("fs");
      if (fs.existsSync(req.file.path)) {
        fs.unlinkSync(req.file.path);
      }
    }

    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 通过uuid查询用户tokens_balance
 * @param {Object} req - 请求对象，请求头中包含uuid
 * @param {Object} res - 响应对象
 */
exports.getTokensBalanceByUuid = async (req, res) => {
  try {
    let uuid;
    // 优先从Authorization header中提取token并解析uuid
    const authHeader = req.headers.authorization;
    if (authHeader && authHeader.startsWith("Bearer ")) {
      try {
        const token = authHeader.substring(7); // 移除 'Bearer ' 前缀
        const jwt = require("jsonwebtoken");
        uuid = jwt.verify(token, process.env.JWT_SECRET).uuid;
      } catch (jwtError) {
        return res.status(401).json({
          success: false,
          message: "无效的认证令牌",
        });
      }
    }
    if (!uuid) {
      return res.status(400).json({
        success: false,
        message: "缺少必要参数：uuid（请通过Bearer token提供）",
      });
    }
    const user = await Visitor.findByPk(uuid, {
      attributes: ["uuid", "tokens_balance"],
    });
    if (!user) {
      return res.status(404).json({
        success: false,
        message: "用户不存在",
      });
    }
    return res.status(200).json({
      success: true,
      message: "查询成功",
      data: {
        uuid: user.uuid,
        tokens_balance: user.tokens_balance,
      },
    });
  } catch (error) {
    console.error("查询tokens_balance错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

/**
 * 用户自助发送邮件接口
 * @param {Object} req - 请求对象，body中包含 content
 * @param {Object} res - 响应对象
 */
exports.sendMailToSelf = async (req, res) => {
  try {
    const nodemailer = require("nodemailer");
    const jwt = require("jsonwebtoken");
    const Visitor = require("../models/Visitor");
    // 1. 解析 token 获取 uuid
    let uuid;
    const authHeader = req.headers.authorization;
    if (authHeader && authHeader.startsWith("Bearer ")) {
      try {
        const token = authHeader.substring(7);
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        uuid = decoded.uuid;
      } catch (jwtError) {
        return res.status(401).json({
          success: false,
          message: "无效的认证令牌",
        });
      }
    }
    if (!uuid) {
      return res.status(400).json({
        success: false,
        message: "缺少必要参数：uuid（请通过Bearer token提供）",
      });
    }
    // 2. 查 Visitor 表获取 email
    const user = await Visitor.findByPk(uuid, { attributes: ["email"] });
    if (!user || !user.email) {
      return res.status(404).json({
        success: false,
        message: "未找到用户邮箱，无法发送邮件",
      });
    }
    // 3. 获取邮件内容
    const { content } = req.body;
    if (!content) {
      return res.status(400).json({
        success: false,
        message: "缺少必要参数：content（邮件内容）",
      });
    }
    // 4. 配置 transporter
    const transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST,
      port: process.env.SMTP_PORT,
      secure: true,
      auth: {
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS,
      },
      tls: {
        rejectUnauthorized: true,
      },
    });
    // 5. 发送邮件
    await transporter.sendMail({
      from: process.env.SMTP_USER,
      to: "support@know1.ai",
      subject: "用户反馈",
      text: content,
      replyTo: user.email,
    });
    return res.status(200).json({
      success: true,
      message: "邮件发送成功",
    });
  } catch (error) {
    console.error("自助邮件发送错误:", error);
    return res.status(500).json({
      success: false,
      message: "服务器内部错误",
      error: process.env.NODE_ENV === "development" ? error.message : undefined,
    });
  }
};

// 通过密码登录
